package com.zerui.manager.accessauthdevice.domainservice;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zerui.basedata.client.PersonnelService;
import com.zerui.cola.dto.Response;
import com.zerui.cola.dto.SingleResponse;
import com.zerui.manager.access.auth.task.domain.AuthTask;
import com.zerui.manager.access.auth.task.gateway.AuthTaskGateway;
import com.zerui.manager.accessauthdevice.AccessAuthDevice;
import com.zerui.manager.accessauthdevice.gateway.AccessAuthDeviceGateWay;
import com.zerui.manager.accessauthorg.gateway.AccessAuthOrgGateWay;
import com.zerui.manager.accessauthorization.gateway.AccessAuthGateWay;
import com.zerui.manager.accessauthpersonnel.gateway.AccessAuthPersonnelGateWay;
import com.zerui.manager.web.cmd.AccessAuthDeviceQryCmd;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
 * @Author wh
 * @create_time 2023-08-23 11:07
 */
@Component
public class AccessAuthDeviceRepository {

	@Resource
	private AccessAuthDeviceGateWay accessAuthDeviceGateWay;
    @Resource
    private AccessAuthOrgGateWay accessAuthOrgGateWay;
    @Resource
    private AccessAuthPersonnelGateWay accessAuthPersonnelGateWay;
    @Resource
    private PersonnelService personnelService;
    @Resource
    private AuthTaskGateway authTaskGateway;


	@Transactional(rollbackFor = Exception.class)
    public void syncAccessAuthDevice(List<AccessAuthDevice> accessAuthDevices, Integer deviceFrom) {

        Map<Long, AccessAuthDevice> accessAuthDeviceMap = accessAuthDeviceGateWay.getAccessAuthDeviceIds(deviceFrom);
        List<AccessAuthDevice> insertList = new ArrayList<>();
        List<AccessAuthDevice> updateList = new ArrayList<>();

        accessAuthDevices.forEach(e->{
            if(accessAuthDeviceMap.containsKey(e.getDeviceId())){
                AccessAuthDevice authDevice = accessAuthDeviceMap.get(e.getDeviceId());
                if(!e.equals(authDevice)){
                    authDevice.setDeviceName(e.getDeviceName());
                    authDevice.setDeviceCode(e.getDeviceCode());
                    authDevice.setDeviceFrom(e.getDeviceFrom()); // 设备源
                    authDevice.setPosition(e.getPosition());
                    authDevice.setType(e.getType());
                    authDevice.setTypeName(e.getTypeName());
                    updateList.add(authDevice);
                }
            }else {
                insertList.add(e);
            }

        });
        Set<Long> ids = accessAuthDevices
                .stream()
                .map(AccessAuthDevice::getDeviceId)
                .collect(Collectors.toSet());
        Set<Long> accessAuthDeviceIds = accessAuthDeviceMap.keySet();

        List<Long> deleteIds = accessAuthDeviceIds.stream().filter(e-> !ids.contains(e)).collect(Collectors.toList());

        accessAuthDeviceGateWay.insertAccessAuthDevice(insertList);
        accessAuthDeviceGateWay.updateBatchDevice(updateList);
        accessAuthDeviceGateWay.deleteAccessAuthByDeviceIds(deleteIds);
    }

    public Page<AccessAuthDevice> getPageList(AccessAuthDeviceQryCmd accessAuthDeviceQryCmd) {
        return accessAuthDeviceGateWay.getPageList(accessAuthDeviceQryCmd);
	}


	public Response update(AccessAuthDevice accessAuthDevice) {
        return accessAuthDeviceGateWay.update(accessAuthDevice);
    }

	public List<AccessAuthDevice> getByDeviceIds(List<Long> deviceIds) {
		return accessAuthDeviceGateWay.getByDeviceIds(deviceIds);
	}

	public Response updateBatch(List<AccessAuthDevice> accessAuthDevices) {
		return accessAuthDeviceGateWay.updateBatch(accessAuthDevices);
	}

    public void devicesDistributePermissions(Long accessAuthId, List<Long> deviceIds) {

        List<Long> orgIds = accessAuthOrgGateWay.getAccessAuthOrgById(accessAuthId);

        List<Long> personals = accessAuthPersonnelGateWay.getAccessAuthPersonnelById(accessAuthId);

        Set<Long> mergePersonnel = getMergePersonnel(orgIds,personals);
        if(CollectionUtils.isEmpty(mergePersonnel)){
            return;
        }
        mergePersonnel = accessAuthPersonnelGateWay.filterAccessAuthPersonnelByIds(accessAuthId,mergePersonnel);
        if(CollectionUtils.isEmpty(mergePersonnel)){
            return;
        }

        authTaskGateway.saveAuthTask(AuthTask.ofBindDevice(accessAuthId, deviceIds, personals));

//       Set<Long> finalPersonnelList = mergePersonnel;
//       CompletableFuture.runAsync(()->{
//            //TODO  新增下发
//            accessAuthGateWay.addDistribute(deviceIds, finalPersonnelList,accessAuthId);
//        });


    }

    public void devicesDeleteDistributePermissions(Long accessAuthId,List<Long> deviceIds) {
        //删除授权 - 设备绑定  返回设备id列表
        deviceIds = accessAuthDeviceGateWay.deleteAccessAuthDeviceById(accessAuthId,deviceIds);
        if(CollectionUtils.isNotEmpty(deviceIds)){
            List<Long> orgIds = accessAuthOrgGateWay.deleteAccessAuthOrgById(accessAuthId);
            //删除授权 - 人员绑定
            List<Long> personals = accessAuthPersonnelGateWay.deleteAccessAuthPersonnelById(accessAuthId);
            Set<Long> personnelList = getMergePersonnel(orgIds,personals);
            if(CollectionUtils.isEmpty(personnelList)){
                return;
            }
            personnelList = accessAuthPersonnelGateWay.filterAccessAuthPersonnelByIds(accessAuthId,personnelList);
            authTaskGateway.saveAuthTask(AuthTask.ofUnbindDevice(accessAuthId, deviceIds, personnelList));
//            List<Long> finalDeviceIds = deviceIds;
//            Set<Long> finalPersonnelList = personnelList;
//            if(CollectionUtils.isNotEmpty(finalPersonnelList)){
//                CompletableFuture.runAsync(()-> accessAuthGateWay.delDistribute(finalDeviceIds, finalPersonnelList));
//            }
        }
    }


    private Set<Long> getMergePersonnel(List<Long> orgIds,List<Long> personals) {

	    List<Long> perLists = new ArrayList<>(personals);
        //查询orgIds部门下的所有人员
        SingleResponse<Map<Long, List<Long>>> result = personnelService.getPersonnelIdsByOrgIds(orgIds);

        Map<Long, List<Long>> map = result.getData();

        if(CollectionUtils.isNotEmpty(map)){
            perLists.addAll(
                    map.values()
                            .stream()
                            .flatMap(List::stream)
                            .collect(Collectors.toList())
            );
        }

	    return new HashSet<>(perLists);
    }


    public void devicesDistributePermissionsByOrges(Long accessAuthId, List<Long> orgIds) {
	    //查询设备
        List<Long> deviceIds = accessAuthDeviceGateWay.getDeviceIdsByAccessAuthId(accessAuthId);

        if(CollectionUtils.isNotEmpty(deviceIds)){

            Set<Long> mergePersonnel = getMergePersonnel(orgIds,new ArrayList<>());
            if(CollectionUtils.isEmpty(mergePersonnel)){
                return;
            }
            mergePersonnel = accessAuthPersonnelGateWay.filterAccessAuthPersonnelByIds(accessAuthId,mergePersonnel);
            authTaskGateway.saveAuthTask(AuthTask.ofBindPersonnel(accessAuthId, deviceIds, mergePersonnel));
//            Set<Long> finalPersonnelList = mergePersonnel;
//            CompletableFuture.runAsync(()->{
//                //TODO 新增下发
//                accessAuthGateWay.addDistribute(deviceIds, finalPersonnelList,accessAuthId);
//            });

        }

	}

    public void devicesDeleteDistributePermissionsByOrges(Long accessAuthId, List<Long> orgIds) {
        List<Long> deviceIds = accessAuthDeviceGateWay.getDeviceIdsByAccessAuthId(accessAuthId);
        if(CollectionUtils.isNotEmpty(deviceIds)){
            Set<Long> mergePersonnel = getMergePersonnel(orgIds,new ArrayList<>());
            if(CollectionUtils.isEmpty(mergePersonnel)){
                return;
            }
            mergePersonnel = accessAuthPersonnelGateWay.filterAccessAuthPersonnelByIds(accessAuthId,mergePersonnel);
            authTaskGateway.saveAuthTask(AuthTask.ofUnbindOrg(accessAuthId, deviceIds, mergePersonnel));
//            Set<Long> finalPersonnelList = mergePersonnel;
//            CompletableFuture.runAsync(()->{
//                //TODO  取消下发
//                accessAuthGateWay.delDistribute(deviceIds, finalPersonnelList);
//            });

        }
	}

    public Long devicesDistributePermissionsByPersonals(Long accessAuthId, List<Long> ids) {
	    List<Long> deviceIds = accessAuthDeviceGateWay.getDeviceIdsByAccessAuthId(accessAuthId);
        Set<Long> persons = new HashSet<>(ids);
        if(CollectionUtils.isNotEmpty(deviceIds)){
            return authTaskGateway.saveAuthTask(AuthTask.ofBindPersonnel(accessAuthId, deviceIds, persons));
//          accessAuthGateWay.addDistribute(deviceIds,persons,accessAuthId);
        }
        return -1l;
	}

    public void devicesDeleteDistributePermissionsByPersonals(Long accessAuthId, List<Long> personnelIds) {
        List<Long> deviceIds = accessAuthDeviceGateWay.getDeviceIdsByAccessAuthId(accessAuthId);
        Set<Long> personsList = new HashSet<>(personnelIds);
        if(CollectionUtils.isNotEmpty(deviceIds)){
            authTaskGateway.saveAuthTask(AuthTask.ofUnbindPersonnel(accessAuthId, deviceIds, personsList));
//            accessAuthGateWay.delDistribute(deviceIds,personsList);
        }
	}

    public void deleteByDeviceId(Long deviceId) {
        accessAuthDeviceGateWay.deleteByDeviceId(deviceId);
    }

    public AccessAuthDevice selectByDeviceId(Long deviceId) {
        return accessAuthDeviceGateWay.getByDeviceId(String.valueOf(deviceId));
    }

    public List<AccessAuthDevice> selectByDeviceIds(Set<Long> deviceIds) {
        return accessAuthDeviceGateWay.selectByDeviceIds(deviceIds);
    }
}
